# -*- coding: utf-8; py-indent-offset:4 -*-
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])
import pandas as pd

import backtrader as bt
import backtrader.indicators as btind

# Create a Stratey
class boll_cross(bt.Strategy):
    params = (
        ('std', 1.1),
        ('period', 24)
    )
    def log(self, txt, dt=None):
        ''' Logging function fot this strategy'''
        dt = dt or self.datas[0].datetime.datetime(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        boll = btind.BollingerBands(self.data, devfactor=self.params.std, period=self.params.period)
        mid, top, bot = boll.mid, boll.top, boll.bot
        self.mid_corss_signal = btind.CrossOver(self.data.close, mid)
        self.top_corss_signal = btind.CrossOver(self.data.close, top)
        self.bot_cross_signal = btind.CrossOver(self.data.close, bot)
        # To keep track of pending orders

        self.order = None



    def next(self):
        if self.position and (abs(self.mid_corss_signal) > 0.0):
            self.order = self.close()

        if not self.position:
            if self.top_corss_signal > 0.0:
                self.order = self.buy()
            if self.bot_cross_signal < 0.0:
                self.order = self.sell()


    def stop(self):
        self.log('%s,%s,%s' %
                 (self.params.std, self.params.period, self.broker.getvalue()))

if __name__ == '__main__':
    # general run strategy
    cerebro = bt.Cerebro()
    cerebro.addwriter(bt.WriterFile, csv=True, out='../backtesting_csv_result/boll_cross.csv')
    cerebro.addobserver(bt.observers.DrawDown)
    cerebro.addobserver(bt.observers.Benchmark)
    cerebro.addobserver(bt.observers.Trades)
    cerebro.addobserver(bt.observers.TimeReturn)
    cerebro.addobserver(bt.observers.DataTrades)
    cerebro.addstrategy(boll_cross)

    dataframe = pd.read_csv('../rbi.csv', index_col=0, parse_dates=True)
    dataframe['openinterest'] = 0
    data = bt.feeds.PandasData(dataname=dataframe)
    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(100000.0)
    cerebro.broker.setcommission(commission=4,
                                 mult=10,
                                 margin=0.1)
    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    # Plot the result

    # cerebro.plot()


    # optimization for the strategy

    # cerebro = bt.Cerebro()
    # cerebro.optstrategy(
    #     boll_cross,
    #     std=[ele * 0.1 for ele in range(10, 80)],
    #     period=range(5,80)
    # )
    # dataframe = pd.read_csv('rbi.csv', index_col=0, parse_dates=True)
    # dataframe['openinterest'] = 0
    # data = bt.feeds.PandasData(dataname=dataframe
    #                            )
    # cerebro.adddata(data)
    # cerebro.broker.setcash(100000.0)
    # cerebro.broker.setcommission(commission=4,
    #                              mult=10,
    #                              margin=0.1)
    #
    # cerebro.run()



